import 'dart:async';

import 'package:e_reception_flutter/singleton/theme_repository/theme_repository.dart';
import 'package:e_reception_flutter/ui/attend_record/attend_record_calendar/attend_record_calendar_page.dart';
import 'package:e_reception_flutter/ui/attend_record/attend_record_calendar/bean/attend_record_calendar_response_bean.dart';
import 'package:e_reception_flutter/ui/attend_record/attend_record_calendar/delegate/attend_record_calendar_item_base_delegate.dart';
import 'package:e_reception_flutter/ui/attend_record/attend_record_calendar/delegate/attend_record_calendar_item_delegate.dart';
import 'package:e_reception_flutter/ui/attend_record/attend_record_calendar/even/attend_record_calendar_refresh_even.dart';
import 'package:e_reception_flutter/utils/vg_toast_utils.dart';
import 'package:e_reception_flutter/vg_widgets/vg_place_holder_status_widget/vg_place_holder_status_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:vg_base/vg_arch_lib.dart';
import 'package:vg_base/vg_base_callback.dart';
import 'package:vg_base/vg_evnet_bus_lib.dart';

import '../attend_record_calendar_view_model.dart';

/// 考勤日历网格组件
///
/// @author: zengxiangxi
/// @createTime: 3/15/21 2:49 PM
/// @specialDemand:
///

class AttendRecordCalendarGridWidget extends StatefulWidget {
  final int index;

  const AttendRecordCalendarGridWidget({Key key, this.index}) : super(key: key);

  @override
  _AttendRecordCalendarGridWidgetState createState() =>
      _AttendRecordCalendarGridWidgetState();
}

class _AttendRecordCalendarGridWidgetState
    extends BaseState<AttendRecordCalendarGridWidget> {
  //根据enum顺序初始化List
  static final List<_WeekItemBean> _WEEK_LIST =
      _WeekType.values.map((_WeekType type) {
    return _WeekItemBean(
        text: type?._toItemString(), isSelected: type?._toSelected());
  }).toList();

  //当前所在年月
  DateTime _dateTime;

  //天总数
  int _dayCount;

  //1号前多少个占位
  int _emptyCount;

  ///项配置
  AttendRecordCalendarItemBaseDelegate _itemDelegate;

  AttendRecordCalendarPageState _pageState;

  Map<int, PunchRecordBean> _dayValueMap;

  bool isLoading = true;

  StreamSubscription _streamSubscription;

  @override
  void initState() {
    super.initState();
    _dayValueMap = Map();
    _pageState = AttendRecordCalendarPageState.of(context);
    final int initPositon = _pageState?.initPostion;
    final DateTime _initDateTime = _pageState?.initDateTime;
    _pageState?.pageValueNotifier?.addListener(_pageListener);
    _streamSubscription = VgEventBus.global.on<AttendRecordCalendarRefreshEven>().listen((event) {
      _getMonthRecordHttp(false, true);
      Future.delayed(Duration(milliseconds: 200),(){
        AttendRecordCalendarPageState.of(context).setPunchRecordBean(_dayValueMap[_itemDelegate?.selectedDay]);
      });
    });
    if (initPositon != null && _initDateTime != null) {
      final int diff = widget.index - initPositon;
      _dateTime = DateTime(
          _initDateTime.year, _initDateTime.month + (diff), 1);
      _dayCount =
          DateTime(_initDateTime.year, _initDateTime.month + 1 + (diff), 0).day;
      _emptyCount = _WeekTypeExtension._getEmptyItemByWeekValue(
          DateTime(_initDateTime.year, _initDateTime.month + (diff), 1)
              .weekday);
      _itemDelegate = AttendRecordCalendarItemDelegate(
        context: context,
        initDateTime: _initDateTime,
        currentDateTime: _dateTime,
        emptyCount: _emptyCount,
        setState: setState,
        onRefresh: (){
          _getMonthRecordHttp(false, true);
        }
      );
      if(_pageState?.pageValueNotifier?.value == widget.index) {
        _getMonthRecordHttp(true,true);
      }else{
        Future.delayed(Duration(milliseconds: 0),(){
          _getMonthRecordHttp(true, false);
        });
      }
    }
  }

  @override
  void dispose() {
    _pageState?.pageValueNotifier?.removeListener(_pageListener);
    _itemDelegate = null;
    _dayValueMap?.clear();
    _dayValueMap = null;
    _pageState = null;
    // print("$_dateTime 销毁");
    _streamSubscription?.cancel();
    super.dispose();
  }

  void _pageListener(){
    if(_pageState?.pageValueNotifier?.value == widget.index){
      Future.delayed(Duration(milliseconds: 0),(){
        _getMonthRecordHttp(true,true);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_dateTime == null ||
        _emptyCount == null ||
        _dayCount == null ||
        _itemDelegate == null) {
      return VgPlaceHolderStatusWidget(
        emptyStatus: true,
      );
    }
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 15),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          _toTitleWidget(),
          _toDayGridViewWidget(),
        ],
      ),
    );
  }

  Widget _toTitleWidget() {
    return Container(
        child: GridView.builder(
            itemCount: _WEEK_LIST.length,
            padding: const EdgeInsets.all(0),
            physics: NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: _WEEK_LIST.length,
              mainAxisSpacing: 0,
              crossAxisSpacing: 10,
              childAspectRatio: 40 / 38,
            ),
            itemBuilder: (BuildContext context, int index) {
              return _toTitleItemWidget(_WEEK_LIST.elementAt(index));
            }));
  }

  Widget _toTitleItemWidget(_WeekItemBean itemBean) {
    return Container(
      child: Center(
        child: Text(
          itemBean?.text ?? "",
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
          style: TextStyle(
            color: (itemBean?.isSelected ?? false)
                ? ThemeRepository.getInstance().getPrimaryColor_1890FF()
                : ThemeRepository.getInstance().getTextMainColor_D0E0F7(),
            fontSize: 12,
          ),
        ),
      ),
    );
  }

  Widget _toDayGridViewWidget() {
    return GridView.builder(
        itemCount: (_dayCount + _emptyCount) ?? 0,
        padding: const EdgeInsets.all(0),
        physics: NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: _WEEK_LIST.length,
          mainAxisSpacing: 16,
          crossAxisSpacing: 10,
          childAspectRatio: 40 / 53,
        ),
        itemBuilder: (BuildContext context, int index) {
          return ClipRRect(
              borderRadius: BorderRadius.circular(2),
              child: _itemDelegate.getItemWidget(
                  index, _dayValueMap[index - _emptyCount + 1]));
        });
  }

  ///获取当前月1号时间戳
  int _getCurrentMonthTimeStramp() {
    if (_dateTime == null) {
      return null;
    }
    return (DateTime(_dateTime.year, _dateTime.month, 1)
                .millisecondsSinceEpoch /
            1000)
        .floor();
  }

  ///获取月信息请求
  void _getMonthRecordHttp(bool isLoadCache,bool isPageChangeNotifier) {
    _pageState?.viewModel?.getRecordByMonthHttp(
        _getCurrentMonthTimeStramp()?.toString(),
        isLoadCache,
        isPageChangeNotifier,
        BaseCallback(onSuccess: (val) {
          AttendRecordCalendarResponseBean bean =
              AttendRecordCalendarResponseBean.fromMap(val);
          _dayValueMap?.clear();
          bean?.data?.punchRecord?.forEach((element) {
            _dayValueMap[element?.day] = element;
            if(element?.day == DateTime?.now()?.day){//判断是否是今天
              VgEventBus.global.send(CardMultiRefreshEvent(element));

            }
          });

          setState(() { });
        }, onError: (msg) {
          print("$_dateTime请求失败：$msg");
        }));
  }

  @override
  void deactivate() {
    // print("$_dateTime deactivate");
    super.deactivate();
  }

}

enum _WeekType {
  Sun,
  Mon,
  Tues,
  Wed,
  Thur,
  Fri,
  Sat,
}

extension _WeekTypeExtension on _WeekType {
  String _toItemString() {
    switch (this) {
      case _WeekType.Mon:
        return "一";
      case _WeekType.Tues:
        return "二";
      case _WeekType.Wed:
        return "三";
      case _WeekType.Thur:
        return "四";
      case _WeekType.Fri:
        return "五";
      case _WeekType.Sat:
        return "六";
      case _WeekType.Sun:
        return "日";
    }
    return null;
  }

  bool _toSelected() {
    switch (this) {
      case _WeekType.Mon:
      case _WeekType.Tues:
      case _WeekType.Wed:
      case _WeekType.Thur:
      case _WeekType.Fri:
        return false;
      case _WeekType.Sat:
      case _WeekType.Sun:
        return true;
    }
    return false;
  }

  static _WeekType _getWeekTypeByWeekValue(int weekValue) {
    if (weekValue == null || weekValue < 1) {
      return null;
    }
    switch (weekValue) {
      case 1:
        return _WeekType.Mon;
      case 2:
        return _WeekType.Tues;
      case 3:
        return _WeekType.Wed;
      case 4:
        return _WeekType.Thur;
      case 5:
        return _WeekType.Fri;
      case 6:
        return _WeekType.Sat;
      case 7:
        return _WeekType.Sun;
    }
    return null;
  }

  static int _getEmptyItemByWeekValue(int weekValue) {
    _WeekType weekType = _getWeekTypeByWeekValue(weekValue);
    if (weekType == null) {
      return null;
    }
    int firstDayPositon = weekType.index;
    return firstDayPositon;
  }
}

class _WeekItemBean {
  final String text;
  final bool isSelected;

  const _WeekItemBean({@required this.text, this.isSelected = false});
}
